import 'dart:math';

import 'package:flutter/material.dart';
import 'package:mobile_app.core/core/presentation/widgets/linear_progress_bar.dart';

const _kGapRatio = 0.1;
const _kMaxGapSize = 8.0;

class SegmentedProgressBar extends StatelessWidget {
  const SegmentedProgressBar({
    super.key,
    required this.progress,
    required this.segmentCount,
    required this.backgroundColor,
    required this.progressColor,
    required this.preferredThickness,
    required this.scaleFactor,
    this.segmentShadow,
  });

  final double progress;
  final int segmentCount;
  final Color backgroundColor;
  final Color progressColor;
  final double preferredThickness;
  final double scaleFactor;
  final BoxShadow? segmentShadow;

  Widget _buildSegment({
    required double ratio,
    required double effectiveThickness,
  }) {
    return LinearProgressBar(
      thickness: effectiveThickness,
      progress: ratio,
      backgroundColor: backgroundColor,
      progressColor: progressColor,
      roundedCap: true,
      shadow: segmentShadow,
    );
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final segmentWidth =
            constraints.maxWidth / (segmentCount + (segmentCount - 1) * _kGapRatio);

        final gapSize = min(segmentWidth * _kGapRatio, _kMaxGapSize * scaleFactor);

        final effectiveThickness = min(preferredThickness * scaleFactor, segmentWidth);

        final segments = <Widget>[];

        for (var i = 0; i < segmentCount; i++) {
          final Widget segment;

          if (progress <= i / segmentCount) {
            segment = _buildSegment(
              ratio: 0.0,
              effectiveThickness: effectiveThickness,
            );
          } else if ((i + 1) / segmentCount <= progress) {
            segment = _buildSegment(
              ratio: 1.0,
              effectiveThickness: effectiveThickness,
            );
          } else {
            segment = _buildSegment(
              ratio: progress * segmentCount - i,
              effectiveThickness: effectiveThickness,
            );
          }

          segments.add(segment);
        }

        final segmentRowWidgets = <Widget>[];

        if (segmentWidth <= preferredThickness * scaleFactor) {
          for (var i = 0; i < segmentCount; i++) {
            if (i > 0) {
              segmentRowWidgets.add(const Spacer());
            }

            segmentRowWidgets.add(SizedBox(
              width: segmentWidth,
              child: segments[i],
            ));
          }
        } else {
          final divider = SizedBox(
            width: gapSize,
          );

          for (var i = 0; i < segmentCount; i++) {
            if (i > 0) {
              segmentRowWidgets.add(divider);
            }

            segmentRowWidgets.add(Expanded(
              child: segments[i],
            ));
          }
        }

        return Row(
          children: segmentRowWidgets,
        );
      },
    );
  }
}
